home *** CD-ROM | disk | FTP | other *** search
- /* Protocol.c */
- /* 27 Jan 1996 21:56:12 */
-
- #ifndef BACKUP_INCLUDE
- #include "IncludeAll.c"
- #endif
- #include "Backup.h"
- #include "Backup_proto.h"
- #include "BackupStrings.h"
-
-
- #define PROTBUFF_SIZE (65536) /* Buffergröße für Protokollfile */
-
-
- static void TranslateProtFileName(char *ProtFileName, size_t MaxLength);
- static short WriteBinProt(struct NameField *file, FILE *fd);
- static BOOL CompressProtFile(const char *ProtFileName);
- static void WriteCompressedProt(struct NameField **nf, char *Bytes, size_t Length);
-
-
- /* aus CmdFile.c */
- extern FILE *aktCmdFile; /* fp für Kommandofile */
- extern char __far CmdFileName[]; /* Name des Kommandofile */
-
-
- /* aus Backup.c */
- extern BPTR aktReadFileHandle; /* fh für Lese-File */
- extern struct BackupOptions myOptions;
- extern unsigned char disknr; /* laufende Nummer der Backup-Diskette */
- extern struct NextFileInfo NFInfo; /* Datensatz für NextFile() */
- extern char StartZeit[8];
- extern struct Window *aktWindow;
-
-
- FILE *ProtFileHandle = NULL; /* File Handle für Protokoll-File */
- BOOL ProtFileValid; // Flag: Protfile enthält sinnvolle Daten (wird am Ende von NamenSchreiben gesetzt)
-
- static char __far NormalizedProtFileName[FMSIZE];
- static unsigned long ProtNfCount; /* kumulierte Anzahl Directory-Einträge (gesamtes Backup) */
- static unsigned long ProtNfLength; /* kumulierte Länge der Directory-Einträge (gesamtes Backup) */
- static fpos_t InfoPos; /* File-Position für :INFO - Zeile */
- static BPTR CompressedProtFileHandle; /* File Handle für komprimierte ProtFiles */
-
-
- void OpenProtFile(void)
- {
- char zeile[129];
- short error = 0;
- BPTR ProtFileLock;
-
- TranslateProtFileName(myOptions.bo_ProtFileName, sizeof(myOptions.bo_ProtFileName));
-
- ProtNfCount = 0l;
- ProtNfLength = 0l;
- InfoPos = 0l;
-
- ProtFileValid = FALSE;
-
- /* ProtFile neu anlegen */
- ProtFileHandle = fopen(myOptions.bo_ProtFileName, "w");
- if (ProtFileHandle)
- fclose(ProtFileHandle);
-
- ProtFileLock = Lock(myOptions.bo_ProtFileName, ACCESS_READ);
- if (ProtFileLock)
- {
- NameFromLock(ProtFileLock, NormalizedProtFileName,
- sizeof(NormalizedProtFileName));
- UnLock(ProtFileLock);
- }
-
- if (NULL == strchr(myOptions.bo_ProtFileName, ':') && *NormalizedProtFileName)
- {
- /* der angebene Filename ist relativ. Er wird jetzt umgesetzt
- in einen absoluten Pfadnamen (mit Device) */
- stccpy(myOptions.bo_ProtFileName, NormalizedProtFileName,
- sizeof(myOptions.bo_ProtFileName));
- }
-
- ProtFileHandle = fopen(myOptions.bo_ProtFileName, "w");
- if (NULL == ProtFileHandle)
- {
- /* Fehler beim Protokollfile anlegen */
- alarm(GetString(MSG_CANNOT_CREATE_PROT), myOptions.bo_ProtFileName, GetIoErrText());
- }
- else if (PT_Binary == myOptions.bo_ProtFile)
- {
- /* Protokoll im Binärformat */
- setvbuf(ProtFileHandle, NULL, _IOFBF, PROTBUFF_SIZE);
-
- error = fwrite(PROTFILEHEADER, sizeof(PROTFILEHEADER), 1, ProtFileHandle) != 1;
- }
- else
- {
- /* Protokoll als Klartext */
- setvbuf(ProtFileHandle, NULL, _IOFBF, PROTBUFF_SIZE);
-
- if (aktCmdFile)
- error = fprintf(ProtFileHandle, GetString(MSG_BACKUP_WITH_CMDFILE_PROT),
- NurName(CmdFileName)) <= 0;
- else
- {
- char c;
-
- strcpy(zeile, IsListEmpty((struct List *) &NFInfo.nfi_FirstDir) ?
- GetString(MSG_LIST) :
- ShortFileName(((struct DirEntry *) NFInfo.nfi_FirstDir.mlh_Head)->Name, 40) );
-
- c = zeile[strlen(zeile)-1];
- if ( c != ':' && c != '/' )
- strcat(zeile, "/");
-
- error = fprintf(ProtFileHandle, GetString(MSG_BACKUP_OF_PROT), zeile) <= 0;
-
- if (!error)
- error = fprintf(ProtFileHandle, GetString(MSG_INCLUDED_FILES_PROT),
- myOptions.bo_IncludeFile.RawName) <= 0;
-
- if (!error && *myOptions.bo_ExcludeFile.RawName)
- error = fprintf(ProtFileHandle, GetString(MSG_EXCLUDED_FILES_PROT),
- myOptions.bo_ExcludeFile.RawName) <= 0;
-
- if (!error && myOptions.bo_UseFirstDate)
- {
- struct myDate datevon;
-
- UnpackDate(myOptions.bo_FirstDate, &datevon);
- error = fprintf(ProtFileHandle, GetString(MSG_ONLYFILESFROM_PROT),
- datevon.Day, datevon.Month, datevon.Year) <= 0;
- }
- if (!error && myOptions.bo_UseLastDate)
- {
- struct myDate datebis;
-
- UnpackDate(myOptions.bo_LastDate, &datebis);
- error = fprintf(ProtFileHandle, GetString(MSG_ONLYFILESUPTO_PROT),
- datebis.Day, datebis.Month, datebis.Year) <= 0;
- }
- }
- if (!error)
- error = fprintf(ProtFileHandle, GetString(MSG_BACKUPSTARTAT_PROT),
- StartZeit[3], StartZeit[2], StartZeit[1]+1980,
- StartZeit[4], StartZeit[5], StartZeit[6] ) <= 0;
-
- /* Anzahl Einträge und Startzeit */
- if (!error)
- {
- fgetpos(ProtFileHandle, &InfoPos);
- error = fprintf(ProtFileHandle, ":INFO %8ld %6ld %6ld\n\n",
- ProtNfCount,
- (StartZeit[3]*100 + StartZeit[2])*100 + StartZeit[1],
- (StartZeit[4]*100 + StartZeit[5])*100 + StartZeit[6] );
- }
-
- if (error)
- error = fprintf(ProtFileHandle, GetString(MSG_PROTHEADER_1)) <= 0;
- if (!error)
- error = fprintf(ProtFileHandle, GetString(MSG_PROTHEADER_2)) <= 0;
-
- }
-
- if (error)
- {
- // Protokoll wird nach Fehler gelöscht
- alarm(GetString(MSG_ERRORWRITING_PROTFILE), myOptions.bo_ProtFileName, GetIoErrText());
- CleanupProtFile(FALSE);
- }
- }
-
-
- static void TranslateProtFileName(char *ProtFileName, size_t MaxLength)
- {
- char Temp[FMSIZE];
- char *p;
-
- stccpy(Temp, ProtFileName, sizeof(Temp));
-
- for (p=Temp; MaxLength && *p;)
- {
- if ('%' == *p)
- {
- p++;
- switch (tolower(*p))
- {
- case 'd': /* Datum einfügen */
- p++;
- if (MaxLength >= 6)
- {
- sprintf(ProtFileName, "%02d%02d%02d",
- (StartZeit[1]+80) % 100, StartZeit[2], StartZeit[3] );
- ProtFileName += 6;
- MaxLength -= 6;
- }
- break;
- case 't': /* Startzeit einfügen */
- p++;
- if (MaxLength >= 6)
- {
- sprintf(ProtFileName, "%02d%02d%02d",
- StartZeit[4], StartZeit[5], StartZeit[6]);
- ProtFileName += 6;
- MaxLength -= 6;
- }
- break;
- default:
- *ProtFileName++ = '%';
- MaxLength--;
- break;
- }
- }
- else
- {
- *ProtFileName++ = *p++;
- MaxLength--;
- }
- }
- }
-
-
- static short WriteBinProt(struct NameField *file, FILE *fd)
- {
- short error;
- unsigned long Flags;
-
- error = fprintf(fd, " %7ld\n", file->FileLen) < 0;
- if (error)
- return error;
-
- Flags = 0l;
- if (file->isComplete)
- Flags |= 0x80000000;
- if (COMPRESS_NONE != file->CompressionType)
- Flags |= 0x40000000 | file->CompressionType;
-
- error = fprintf(fd, "X %lx %ld %lx %lx %lx %lx %d %d %lx\n",
- file->Offset,
- file->RecordedLen,
- file->FileDate.ds_Days, file->FileDate.ds_Minute,
- file->FileDate.ds_Tick,
- file->Protection,
- file->Extension, file->SessionNr, Flags
- ) < 0;
- if (error)
- return error;
-
- if (file->NameLen > strlen(file->Name))
- {
- /* Filenote schreiben */
- error = fprintf(fd, "O %s\n", file->Name + strlen(file->Name) + 1) < 0;
- }
-
- return error;
- }
-
-
- /* Alle Files einer Diskette in das ProtFile eintragen */
- void WriteProtFile(struct NameField *file, unsigned char disknr)
- {
- size_t len;
- short error = 0;
- char *fname, Kenn='F';
- struct NameField *aktNf;
- short ShortDiskNr = disknr;
- InfoLineHandle Pil;
-
- ASSERT_VALID(file);
-
- SetBusyPointer(aktWindow, TRUE);
- Pil = PushInfoLine(GetString(MSG_WRITING_PROTFILE));
-
- switch (myOptions.bo_ProtFile)
- {
- case PT_Binary:
- while (!error && file)
- {
- ProtNfCount++;
- len = NF_LEN(file);
- ProtNfLength += len + sizeof(short);
-
- error = fwrite(&ShortDiskNr, sizeof(short), 1, ProtFileHandle) != 1
- || fwrite(file, len, 1, ProtFileHandle) != 1;
-
- file = file->NextName;
- }
- break;
-
- case PT_ASCII:
- /* Einträge zählen und in den Kopf des Protokollfiles eintragen */
- for (aktNf=file; aktNf; aktNf=aktNf->NextName)
- ProtNfCount++;
-
- while (!error && file)
- {
- ProtNfLength += NF_LEN(file);
-
- len = strlen(file->Name) + 2;
- fname = file->Name;
- while (!error && len)
- {
- if (Kenn != 'C' && (file->isSoftLink))
- Kenn = 'L';
- if (Kenn != 'C' && (file->isHardLink))
- Kenn = 'H';
- if (Kenn != 'C' && (file->isDir))
- Kenn = 'E';
- if (Kenn != 'C' && (file->isPartition))
- Kenn = 'P';
-
- if (len <= PROT_FNAME_LEN)
- {
- /* Name paßt in eine Zeile */
- error = fprintf(ProtFileHandle, "%c %-3d \"%s\"%*s",
- file->Extension ? tolower(Kenn) : Kenn,
- disknr, fname,
- PROT_FNAME_LEN-len, "") < 0;
-
- if (Kenn != 'C')
- error = error || WriteBinProt(file, ProtFileHandle);
- else
- error = fprintf(ProtFileHandle, "\n") < 0;
-
- len = 0;
- Kenn = 'F';
- }
- else
- {
- /* Verlängerungszeile für Filenamen */
- error = fprintf(ProtFileHandle, "%c %-3d \"%*.*s»",
- file->Extension ? tolower(Kenn) : Kenn,
- disknr,
- PROT_FNAME_LEN-2, PROT_FNAME_LEN-2,
- fname) < 0;
-
- if (Kenn != 'C')
- error = error || WriteBinProt(file, ProtFileHandle);
- else
- error = fprintf(ProtFileHandle, "\n") < 0;
-
- Kenn = 'C';
- fname += PROT_FNAME_LEN-2;
- len -= PROT_FNAME_LEN-2;
- }
- }
- file = file->NextName;
- }
- break;
- }
-
- SetBusyPointer(aktWindow, FALSE);
- PopInfoLine(&Pil);
-
- if (error)
- {
- // Protokoll wird nach Fehler gelöscht
- alarm(GetString(MSG_ERRORWRITING_PROTFILE), myOptions.bo_ProtFileName, GetIoErrText());
- CleanupProtFile(FALSE);
- }
- }
-
-
- void CleanupProtFile(BOOL KeepProtFile)
- {
- if (ProtFileHandle)
- {
- switch (myOptions.bo_ProtFile)
- {
- case PT_Binary:
- {
- struct DiskLabel ProtLabel;
-
- BuildDiskLabel(&ProtLabel, disknr);
-
- ProtLabel.DirAnz = ProtNfCount;
- ProtLabel.DirLen = ProtNfLength;
-
- // Label-Prüfsumme korrigieren!
- ProtLabel.LabelCheckSum = 0l;
- ProtLabel.LabelCheckSum = -ComputeLabelCheckSum(&ProtLabel);
-
- fwrite(&ProtLabel, sizeof(ProtLabel), 1, ProtFileHandle);
- }
- break;
-
- case PT_ASCII:
- if (InfoPos)
- {
- /* endgültige Anzahl Einträge und Startzeit eintragen */
- if (fsetpos(ProtFileHandle, &InfoPos) == 0)
- {
- fprintf(ProtFileHandle, ":INFO %8ld %6ld %6ld\n\n",
- ProtNfCount,
- (StartZeit[3]*100 + StartZeit[2])*100 + StartZeit[1],
- (StartZeit[4]*100 + StartZeit[5])*100 + StartZeit[6] );
- }
- }
- InfoPos = 0;
- break;
- }
-
- fclose(ProtFileHandle);
- ProtFileHandle = NULL;
- }
-
- if (!KeepProtFile && !ProtFileValid)
- {
- // wenn nicht wenigstens einmal NamenSchreiben erfolgreich beendet wurde, dann
- // steht nur Schrott im ProtFile.. Also wird es dann gelöscht!
- DeleteFile(myOptions.bo_ProtFileName);
- }
- }
-
-
- void CompressProtocol(void)
- {
- if (PT_Binary == myOptions.bo_ProtFile && myOptions.bo_KeepProtFile)
- {
- // binäre nicht-temporäre Protfiles werden automatisch komprimiert
- CompressProtFile(myOptions.bo_ProtFileName);
- }
- }
-
-
- BOOL isProtFile(const char *Path, const char *FileName)
- {
- char FilePath[FMSIZE];
-
- if (NULL == ProtFileHandle)
- return FALSE;
-
- stccpy(FilePath, Path, sizeof(FilePath));
- if (!AddPart(FilePath, (STRPTR) FileName, sizeof(FilePath)))
- return FALSE;
-
- return (BOOL) (stricmp(FilePath, NormalizedProtFileName) == 0);
- }
-
-
- static BOOL CompressProtFile(const char *ProtFileName)
- {
- char *TempName;
- BOOL Result = FALSE;
- struct NameField *ProtNF = NULL;
- InfoLineHandle Pil;
-
- SetBusyPointer(aktWindow, TRUE);
- Pil = PushInfoLine(GetString(MSG_COMPRESSING_PROTFILE));
-
- while (1)
- {
- char ProtFilePath[FMSIZE];
- static struct FileInfoBlock __aligned fib;
-
- if (!InitCompress())
- break;
-
- stcgfp(ProtFilePath, ProtFileName);
- AddPart(ProtFilePath, (STRPTR) "Prot", sizeof(ProtFilePath));
-
- TempName = tempname(ProtFilePath);
- if (NULL == TempName)
- break;
-
- aktReadFileHandle = Open((STRPTR) ProtFileName, MODE_OLDFILE);
- if (NULL == aktReadFileHandle)
- break;
-
- if (!ExamineFH(aktReadFileHandle, &fib))
- break;
-
- ProtNF = calloc(sizeof(struct NameField) + strlen(ProtFileName), 1);
- if (NULL == ProtNF)
- break;
-
- FillNameField(ProtNF, &fib);
- strcpy(ProtNF->Name, ProtFileName);
-
- if (!Rename((STRPTR) ProtFileName, FilePart((STRPTR) TempName)))
- break;
-
- CompressedProtFileHandle = Open((STRPTR) ProtFileName, MODE_NEWFILE);
- if (NULL == CompressedProtFileHandle)
- break;
-
- // Header für komprimiertes ProtFile schreiben
- Write(CompressedProtFileHandle, (STRPTR) COMPRESSEDPROTFILEHEADER,
- sizeof(COMPRESSEDPROTFILEHEADER));
-
- // Länge des unkomprimierten Files hier merken!
- Write(CompressedProtFileHandle, &fib.fib_Size,
- sizeof(fib.fib_Size));
-
- // PROTFILEHEADER überlesen
- Seek(aktReadFileHandle, sizeof(PROTFILEHEADER), OFFSET_BEGINNING);
- ProtNF->FileLen -= sizeof(PROTFILEHEADER);
-
- CompressFile(ProtNF, ProtNF->FileLen, WriteCompressedProt);
- Close(aktReadFileHandle);
- aktReadFileHandle = NULL;
- Result = TRUE;
- break;
- }
-
- if (CompressedProtFileHandle)
- {
- Close(CompressedProtFileHandle);
- CompressedProtFileHandle = NULL;
- }
- if (TempName)
- {
- if (Result)
- DeleteFile(TempName); // altes (unkomprimiertes) ProtFile löschen
- else
- Rename(TempName, FilePart((STRPTR) ProtFileName)); // Originales ProtFile wiederherstellen
-
- free(TempName);
- }
- if (ProtNF)
- free(ProtNF);
-
- SetBusyPointer(aktWindow, FALSE);
- PopInfoLine(&Pil);
-
- return Result;
- }
-
-
- static void WriteCompressedProt(struct NameField **nf, char *Bytes, size_t Length)
- {
- if (CompressedProtFileHandle)
- Write(CompressedProtFileHandle, Bytes, Length);
- }
-